<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Transaction;
use App\Models\Tenant;
use Carbon\Carbon;

class TransactionSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // 获取所有租户
        $tenants = Tenant::all();
        
        if ($tenants->isEmpty()) {
            $this->command->warn('没有找到租户数据，请先运行 TenantSeeder');
            return;
        }

        $this->command->info('开始创建交易账单测试数据...');

        // 落地公司列表
        $landingCompanies = [
            '北京乐业科技有限公司',
            '上海创新数字技术有限公司', 
            '深圳智能科技发展有限公司',
            '广州云端服务有限公司',
            '杭州数字化解决方案有限公司',
            '成都智慧科技有限公司',
            '武汉创新技术有限公司',
            '西安数字科技有限公司',
            '南京智能服务有限公司',
            '青岛海洋科技有限公司'
        ];

        // 交易类型权重分布
        $typeWeights = [
            'income' => 45,  // 入账 45%
            'expense' => 55  // 出账 55%
        ];

        // 入账子类型权重
        $incomeSubTypeWeights = [
            'recharge' => 60,       // 充值 60%
            'refund_ticket' => 25,  // 退款退票 25%
            'platform_add' => 15    // 平台加款 15%
        ];

        // 出账子类型权重
        $expenseSubTypeWeights = [
            'settlement' => 80,      // 结算 80%
            'balance_refund' => 20   // 余额退账 20%
        ];

        // 状态权重分布
        $statusWeights = [
            'pending' => 5,      // 待处理 5%
            'processing' => 10,  // 处理中 10%
            'completed' => 70,   // 已完成 70%
            'failed' => 10,      // 失败 10%
            'cancelled' => 5     // 已取消 5%
        ];

        // 交易摘要模板
        $summaryTemplates = [
            // 入账摘要
            'income' => [
                'recharge' => [
                    '充值到账',
                    '账户充值成功',
                    '预付款充值',
                    '资金充值入账'
                ],
                'refund_ticket' => [
                    '退款退票到账',
                    '订单退款',
                    '服务费退款',
                    '多收费用退款'
                ],
                'platform_add' => [
                    '平台补贴',
                    '奖励金到账',
                    '推广奖励',
                    '系统调增'
                ]
            ],
            // 出账摘要
            'expense' => [
                'settlement' => [
                    '结算支出',
                    '自由职业者结算',
                    '项目结算',
                    '月度结算支出'
                ],
                'balance_refund' => [
                    '余额退款',
                    '用户提现',
                    '账户余额退回',
                    '多余资金退还'
                ]
            ]
        ];

        $totalTransactions = 0;

        foreach ($tenants as $tenant) {
            // 每个租户创建50-150条交易记录
            $transactionCount = rand(50, 150);
            $currentBalance = rand(100000, 1000000); // 初始余额10万-100万
            
            for ($i = 0; $i < $transactionCount; $i++) {
                // 根据权重随机选择交易类型
                $type = $this->getWeightedRandomChoice($typeWeights);
                
                // 根据交易类型选择子类型
                if ($type === 'income') {
                    $subType = $this->getWeightedRandomChoice($incomeSubTypeWeights);
                } else {
                    $subType = $this->getWeightedRandomChoice($expenseSubTypeWeights);
                }
                
                // 根据权重随机选择状态
                $status = $this->getWeightedRandomChoice($statusWeights);
                
                // 生成交易时间（最近6个月内）
                $transactionTime = Carbon::now()->subDays(rand(0, 180))->subHours(rand(0, 23))->subMinutes(rand(0, 59));
                
                // 生成交易金额
                $amount = $this->generateRealisticAmount($type, $subType);
                
                // 计算交易后余额
                if ($type === 'income') {
                    $newBalance = $currentBalance + $amount;
                } else {
                    $newBalance = $currentBalance - $amount;
                    // 确保余额不为负数
                    if ($newBalance < 0) {
                        $amount = $currentBalance * 0.8; // 最多支出当前余额的80%
                        $newBalance = $currentBalance - $amount;
                    }
                }
                
                // 生成交易摘要
                $summaryOptions = $summaryTemplates[$type][$subType];
                $summary = $summaryOptions[array_rand($summaryOptions)];
                
                // 生成详细描述（30%概率有描述）
                $description = null;
                if (rand(0, 100) < 30) {
                    $description = $this->generateDescription($type, $subType, $amount);
                }
                
                // 生成处理时间
                $processedAt = null;
                if (in_array($status, ['completed', 'failed', 'cancelled'])) {
                    $processedAt = $transactionTime->copy()->addHours(rand(1, 48));
                }

                // 创建交易记录（带重试机制）
                $maxRetries = 3;
                $created = false;
                
                for ($retry = 0; $retry < $maxRetries && !$created; $retry++) {
                    try {
                        Transaction::create([
                            'tenant_id' => $tenant->id,
                            'type' => $type,
                            'sub_type' => $subType,
                            'amount' => $amount,
                            'balance_after' => $newBalance,
                            'landing_company' => $landingCompanies[array_rand($landingCompanies)],
                            'status' => $status,
                            'summary' => $summary,
                            'description' => $description,
                            'metadata' => $this->generateMetadata($type, $subType, $status),
                            'transaction_time' => $transactionTime,
                            'processed_at' => $processedAt,
                            'created_by' => 1,
                            'processed_by' => $processedAt ? rand(1, 3) : null,
                        ]);
                        $created = true;
                    } catch (\Illuminate\Database\QueryException $e) {
                        if ($e->errorInfo[1] == 1062) { // 重复键错误
                            // 稍微延迟后重试
                            usleep(1000); // 1毫秒延迟
                            continue;
                        }
                        throw $e; // 其他错误直接抛出
                    }
                }
                
                if (!$created) {
                    $this->command->warn("无法创建交易记录，跳过此条");
                    continue;
                }
                
                // 如果是已完成的交易，更新当前余额
                if ($status === 'completed') {
                    $currentBalance = $newBalance;
                }
                
                $totalTransactions++;
            }
            
            $this->command->info("租户 {$tenant->company_name} 创建了 {$transactionCount} 条交易记录");
        }

        $this->command->info("交易账单测试数据创建完成！总计创建 {$totalTransactions} 条记录");
    }

    /**
     * 根据权重随机选择
     */
    private function getWeightedRandomChoice($weights)
    {
        $total = array_sum($weights);
        $random = rand(1, $total);
        $current = 0;
        
        foreach ($weights as $choice => $weight) {
            $current += $weight;
            if ($random <= $current) {
                return $choice;
            }
        }
        
        return array_key_first($weights);
    }

    /**
     * 生成真实的金额分布
     */
    private function generateRealisticAmount($type, $subType)
    {
        $rand = rand(1, 100);
        
        // 入账金额通常较大
        if ($type === 'income') {
            if ($subType === 'recharge') {
                // 充值：1万-100万
                if ($rand <= 40) return rand(10000, 50000) + (rand(0, 99) / 100);
                if ($rand <= 70) return rand(50000, 200000) + (rand(0, 99) / 100);
                if ($rand <= 90) return rand(200000, 500000) + (rand(0, 99) / 100);
                return rand(500000, 1000000) + (rand(0, 99) / 100);
            } elseif ($subType === 'refund_ticket') {
                // 退款：100-5万
                if ($rand <= 60) return rand(100, 5000) + (rand(0, 99) / 100);
                if ($rand <= 85) return rand(5000, 20000) + (rand(0, 99) / 100);
                return rand(20000, 50000) + (rand(0, 99) / 100);
            } else { // platform_add
                // 平台加款：10-1万
                if ($rand <= 70) return rand(10, 1000) + (rand(0, 99) / 100);
                if ($rand <= 90) return rand(1000, 5000) + (rand(0, 99) / 100);
                return rand(5000, 10000) + (rand(0, 99) / 100);
            }
        } else { // expense
            if ($subType === 'settlement') {
                // 结算：500-50万
                if ($rand <= 50) return rand(500, 10000) + (rand(0, 99) / 100);
                if ($rand <= 75) return rand(10000, 50000) + (rand(0, 99) / 100);
                if ($rand <= 90) return rand(50000, 200000) + (rand(0, 99) / 100);
                return rand(200000, 500000) + (rand(0, 99) / 100);
            } else { // balance_refund
                // 余额退账：100-10万
                if ($rand <= 60) return rand(100, 5000) + (rand(0, 99) / 100);
                if ($rand <= 85) return rand(5000, 30000) + (rand(0, 99) / 100);
                return rand(30000, 100000) + (rand(0, 99) / 100);
            }
        }
    }

    /**
     * 生成详细描述
     */
    private function generateDescription($type, $subType, $amount)
    {
        $descriptions = [
            'income' => [
                'recharge' => "充值金额：¥" . number_format($amount, 2) . "，来源：银行转账",
                'refund_ticket' => "退款处理，原因：服务取消，退款金额：¥" . number_format($amount, 2),
                'platform_add' => "平台奖励发放，金额：¥" . number_format($amount, 2)
            ],
            'expense' => [
                'settlement' => "结算支出，涉及金额：¥" . number_format($amount, 2) . "，已转账至自由职业者账户",
                'balance_refund' => "用户申请余额退款，退款金额：¥" . number_format($amount, 2)
            ]
        ];
        
        return $descriptions[$type][$subType] ?? null;
    }

    /**
     * 生成元数据
     */
    private function generateMetadata($type, $subType, $status)
    {
        $metadata = [
            'transaction_source' => 'system',
            'ip_address' => $this->generateRandomIP(),
        ];
        
        if ($status === 'completed') {
            $metadata['completed_at'] = now()->toISOString();
            $metadata['processor'] = 'auto_system';
        } elseif ($status === 'failed') {
            $metadata['failure_reason'] = $this->getRandomFailureReason();
        }
        
        if ($type === 'income' && $subType === 'recharge') {
            $metadata['payment_method'] = rand(0, 1) ? 'bank_transfer' : 'alipay';
        }
        
        return $metadata;
    }

    /**
     * 生成随机IP地址
     */
    private function generateRandomIP()
    {
        return rand(1, 255) . '.' . rand(1, 255) . '.' . rand(1, 255) . '.' . rand(1, 255);
    }

    /**
     * 获取随机失败原因
     */
    private function getRandomFailureReason()
    {
        $reasons = [
            '银行系统维护',
            '账户余额不足',
            '网络连接超时',
            '交易金额异常',
            '系统处理异常',
            '用户取消操作'
        ];
        
        return $reasons[array_rand($reasons)];
    }
}